package eclipse.util.io;
import java.io.*;
import java.net.URL;
import java.util.*;
import eclipse.ErrorManager;
/**
 * The PropertyFile Class represents a PropertyFile that the system can read or write.
 * A PropertyFile is the successor to the ini file from EE 2.7 and supports much more depth.
 * If the PropertyFile is specified from an InputStream, the PropertyFile is READ ONLY.
 */
/*
 * Copyright (c) 2009, TOD Productions All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
 *	- Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
 *	- Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
 *	-Neither the name of the organization nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */
public final class PropertyFile
{
	//Interface to the PropertyFile
	private final Properties pFile;// = new Properties();
	//Name of the file
	private String sFileName;
	/** 
	 * Loads a new PropertyFile from a specified path.
	 * @param sFile String path to the property file.
	 */
	public PropertyFile(String sFile)
	{
		//Creates the object required to read the property file
		pFile = new Properties();
		//load the property file from a String
		loadProperty(sFile);
	}
	/**
	 * Streams and loads a new PropertyFile from a remote or local location.
	 * @param iFile Stream that the PropertyFile is loaded from.
	 */
	public PropertyFile(InputStream iFile)
	{
		//Create the object required to read the property file
		pFile = new Properties();
		//load the property file from an InputStream
		loadProperty(iFile);
	}
	/**
	 * Streams and loads a new PropertyFile from a remote location.
	 * @param uFile URL path to the PropertyFile, most likely an Internet path.
	 */
	public PropertyFile(URL uFile)
	{
		//Create the object required to read the property file
		pFile = new Properties();
		//load the property file from a URL
		loadProperty(uFile);
	}
	/**
	 * Reads a value from a PropertyFile.
	 * @param sKey A set of keys and subkeys that the property file reads.
	 */
	public final String readProperty(String... sKey)
	{
		//create the temporary String
		String sTemp = "";
		//scroll through the array of Strings
		for(int i = 0; i < sKey.length; i++)
		{
			//add the String to the structured String
			sTemp = sTemp + sKey[i];
			//Check if the next String is the last
			if(i < (sKey.length - 1))
			{
				//Seperate sections with a '.'
				sTemp = sTemp + ".";
			}
		}		
		//return the data from the structured String
		return readProperty(sTemp);
	}
	/**
	 * Reads a value from a PropertyFile.
	 * @param sKey A single key with no subkeys that the property file reads.
	 */
	public final String readProperty(String sKey)
	{
		//return the data from the key
		return pFile.getProperty(sKey);
	}
	/**
	 * Writes a value to a Property File.
	 * @param sValue Value to be written to the PropertyFile
	 * @param sKey A Set of keys and subkeys that the value is related to.
	 */
	public final void writeProperty(String sValue, String... sKey)
	{
		//Create the temporary String
		String sTemp = "";
		//Scroll through the keys
		for(int i = 0; i < sKey.length; i++)
		{
			//Join the keys
			sTemp = sTemp + sKey[i];
			//Add a period between keys
			if(i < (sKey.length - 1))
				sTemp = sTemp + ".";
		}
		//write the key to the PropertyFile
		writeProperty(sTemp, sValue);
	}
	/**
	 * Writes a value to a PropertyFile with only a single key.
	 * @param sKey Key that the value is related to.
	 * @param sValue Value to be written to the PropertyFile.
	 */
	public final void writeProperty(String sKey, String sValue)
	{
		//Attempt to write to the file
		try
		{
			//Add the value to the file
			pFile.setProperty(sKey, sValue);
			//save the PropertyFile
			pFile.store(new FileOutputStream(sFileName), "");
		}
		//An error occurred because the file did not exist
		catch(FileNotFoundException e)
		{
			//make the file because it did not exist
			IOTools.makeFile(sFileName);
		}
		//An unexpected error occurred so let the Eclipse ErrorManager handle it.
		catch(Exception e)
		{			
			ErrorManager.handleError(e);
		}
	}
	/**
	 * Loads a PropertyFile from a remote location.
	 * @param uFile URL path to the file.
	 */
	public final void loadProperty(URL uFile)
	{
		loadProperty(uFile.getFile());
	}
	/**
	 * Opens a Stream pointing to the PropertyFile located remotely or localy.
	 * @param iFile InputStream related to the file.
	 */
	public final void loadProperty(InputStream iFile)
	{
		//try to load the property file
		try
		{
			pFile.load(iFile);
		}
		//An error occurred loading so handle it
		catch (Exception e)
		{
			ErrorManager.handleError(e);
		}
	}
	/**
	 * Loads a PropertyFile from a specified String path. This is the only way to write to a PropertyFile.
	 * @param sFile String path pointing to the PropertyFile.
	 */
	public final void loadProperty(String sFile)
	{
		//Try to load a PropertyFile
		try
		{
			//Create a new inputStream based off of the String-path
			FileInputStream Fin = new FileInputStream(sFile);
			//Load the file
			pFile.load(Fin);
			//save the String name
			sFileName = sFile;
		}
		//Handle the error
		catch(Exception e)
		{
			ErrorManager.handleError(e);
		}
	}
	/**
	 * Closes the PropertyFile.
	 */
	public final void closeProperty()
	{		
		//Clear the property
		pFile.clear();
	}
	public void finalize()
	{
		//free up the file.
		closeProperty();
	}
}
